import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import '../app_logger.dart';

/// 全局SharedPreferences工具类
/// 提供简单易用的缓存存储和读取功能
class PreferenceUtils {
  static SharedPreferences? _prefs;
  static PreferenceUtils? _instance;
  
  static PreferenceUtils get instance => _instance ??= PreferenceUtils._();
  
  PreferenceUtils._();
  
  /// 初始化SharedPreferences
  /// 建议在main()函数中调用
  static Future<void> initialize() async {
    _prefs = await SharedPreferences.getInstance();
    log.d('📱 PreferenceUtils 初始化完成');
  }
  
  /// 确保已初始化
  static void _ensureInitialized() {
    if (_prefs == null) {
      throw Exception('PreferenceUtils未初始化，请先调用PreferenceUtils.initialize()');
    }
  }
  
  // ==================== 字符串相关 ====================
  
  /// 保存字符串
  static Future<bool> setString(String key, String value) async {
    _ensureInitialized();
    final result = await _prefs!.setString(key, value);
    log.d('💾 保存字符串: $key = $value');
    return result;
  }
  
  /// 获取字符串
  static String? getString(String key, {String? defaultValue}) {
    _ensureInitialized();
    final value = _prefs!.getString(key) ?? defaultValue;
    log.d('📖 读取字符串: $key = $value');
    return value;
  }
  
  // ==================== 整数相关 ====================
  
  /// 保存整数
  static Future<bool> setInt(String key, int value) async {
    _ensureInitialized();
    final result = await _prefs!.setInt(key, value);
    log.d('💾 保存整数: $key = $value');
    return result;
  }
  
  /// 获取整数
  static int? getInt(String key, {int? defaultValue}) {
    _ensureInitialized();
    final value = _prefs!.getInt(key) ?? defaultValue;
    log.d('📖 读取整数: $key = $value');
    return value;
  }
  
  // ==================== 布尔值相关 ====================
  
  /// 保存布尔值
  static Future<bool> setBool(String key, bool value) async {
    _ensureInitialized();
    final result = await _prefs!.setBool(key, value);
    log.d('💾 保存布尔值: $key = $value');
    return result;
  }
  
  /// 获取布尔值
  static bool? getBool(String key, {bool? defaultValue}) {
    _ensureInitialized();
    final value = _prefs!.getBool(key) ?? defaultValue;
    log.d('📖 读取布尔值: $key = $value');
    return value;
  }
  
  // ==================== 浮点数相关 ====================
  
  /// 保存浮点数
  static Future<bool> setDouble(String key, double value) async {
    _ensureInitialized();
    final result = await _prefs!.setDouble(key, value);
    log.d('💾 保存浮点数: $key = $value');
    return result;
  }
  
  /// 获取浮点数
  static double? getDouble(String key, {double? defaultValue}) {
    _ensureInitialized();
    final value = _prefs!.getDouble(key) ?? defaultValue;
    log.d('📖 读取浮点数: $key = $value');
    return value;
  }
  
  // ==================== 字符串列表相关 ====================
  
  /// 保存字符串列表
  static Future<bool> setStringList(String key, List<String> value) async {
    _ensureInitialized();
    final result = await _prefs!.setStringList(key, value);
    log.d('💾 保存字符串列表: $key = $value');
    return result;
  }
  
  /// 获取字符串列表
  static List<String>? getStringList(String key, {List<String>? defaultValue}) {
    _ensureInitialized();
    final value = _prefs!.getStringList(key) ?? defaultValue;
    log.d('📖 读取字符串列表: $key = $value');
    return value;
  }
  
  // ==================== JSON对象相关 ====================
  
  /// 保存JSON对象（自动序列化）
  static Future<bool> setJson(String key, Map<String, dynamic> value) async {
    _ensureInitialized();
    try {
      final jsonString = jsonEncode(value);
      final result = await _prefs!.setString(key, jsonString);
      log.d('💾 保存JSON对象: $key = $value');
      return result;
    } catch (e) {
      log.d('❌ 保存JSON对象失败: $key, 错误: $e');
      return false;
    }
  }
  
  /// 获取JSON对象（自动反序列化）
  static Map<String, dynamic>? getJson(String key, {Map<String, dynamic>? defaultValue}) {
    _ensureInitialized();
    try {
      final jsonString = _prefs!.getString(key);
      if (jsonString == null) {
        log.d('📖 读取JSON对象: $key = $defaultValue (未找到)');
        return defaultValue;
      }
      
      final value = jsonDecode(jsonString) as Map<String, dynamic>;
      log.d('📖 读取JSON对象: $key = $value');
      return value;
    } catch (e) {
      log.d('❌ 读取JSON对象失败: $key, 错误: $e, 返回默认值: $defaultValue');
      return defaultValue;
    }
  }
  
  // ==================== 通用操作 ====================
  
  /// 检查键是否存在
  static bool containsKey(String key) {
    _ensureInitialized();
    final exists = _prefs!.containsKey(key);
    log.d('🔍 检查键存在: $key = $exists');
    return exists;
  }
  
  /// 删除指定键
  static Future<bool> remove(String key) async {
    _ensureInitialized();
    final result = await _prefs!.remove(key);
    log.d('🗑️ 删除键: $key');
    return result;
  }
  
  /// 清空所有数据
  static Future<bool> clear() async {
    _ensureInitialized();
    final result = await _prefs!.clear();
    log.d('🧹 清空所有缓存数据');
    return result;
  }
  
  /// 获取所有键
  static Set<String> getAllKeys() {
    _ensureInitialized();
    final keys = _prefs!.getKeys();
    log.d('📋 获取所有键: $keys');
    return keys;
  }
  
  // ==================== 便捷方法 ====================
  
  /// 保存时间戳
  static Future<bool> setTimestamp(String key, {DateTime? time}) async {
    final timestamp = (time ?? DateTime.now()).millisecondsSinceEpoch;
    return await setInt(key, timestamp);
  }
  
  /// 获取时间戳
  static DateTime? getTimestamp(String key) {
    final timestamp = getInt(key);
    if (timestamp == null) return null;
    return DateTime.fromMillisecondsSinceEpoch(timestamp);
  }
  
  /// 检查时间戳是否过期
  static bool isTimestampExpired(String key, Duration expireDuration) {
    final timestamp = getTimestamp(key);
    if (timestamp == null) return true;
    return DateTime.now().difference(timestamp) > expireDuration;
  }
  
  /// 保存应用版本信息
  static Future<bool> setAppVersion(String version) async {
    return await setString('app_version', version);
  }
  
  /// 获取应用版本信息
  static String? getAppVersion() {
    return getString('app_version');
  }
  
  /// 检查是否是首次启动
  static bool isFirstLaunch() {
    return !containsKey('first_launch_completed');
  }
  
  /// 标记首次启动完成
  static Future<bool> markFirstLaunchCompleted() async {
    return await setBool('first_launch_completed', true);
  }
  
  // ==================== 调试方法 ====================
  
  /// 打印所有存储的数据（调试用）
  static void debugPrintAll() {
    _ensureInitialized();
    final keys = _prefs!.getKeys();
    log.d('📊 ===== PreferenceUtils 调试信息 =====');
    for (final key in keys) {
      try {
        final value = _prefs!.get(key);
        log.d('📊 $key: $value (${value.runtimeType})');
      } catch (e) {
        log.d('📊 $key: 读取失败 ($e)');
      }
    }
    log.d('📊 ===== 总计 ${keys.length} 个键值对 =====');
  }
}

/// 便捷的静态方法别名，减少代码冗余
class Prefs {
  static Future<bool> setString(String key, String value) => PreferenceUtils.setString(key, value);
  static String? getString(String key, [String? defaultValue]) => PreferenceUtils.getString(key, defaultValue: defaultValue);
  
  static Future<bool> setInt(String key, int value) => PreferenceUtils.setInt(key, value);
  static int? getInt(String key, [int? defaultValue]) => PreferenceUtils.getInt(key, defaultValue: defaultValue);
  
  static Future<bool> setBool(String key, bool value) => PreferenceUtils.setBool(key, value);
  static bool? getBool(String key, [bool? defaultValue]) => PreferenceUtils.getBool(key, defaultValue: defaultValue);
  
  static Future<bool> setDouble(String key, double value) => PreferenceUtils.setDouble(key, value);
  static double? getDouble(String key, [double? defaultValue]) => PreferenceUtils.getDouble(key, defaultValue: defaultValue);
  
  static Future<bool> setJson(String key, Map<String, dynamic> value) => PreferenceUtils.setJson(key, value);
  static Map<String, dynamic>? getJson(String key, [Map<String, dynamic>? defaultValue]) => PreferenceUtils.getJson(key, defaultValue: defaultValue);
  
  static Future<bool> setTimestamp(String key, {DateTime? time}) => PreferenceUtils.setTimestamp(key, time: time);
  static DateTime? getTimestamp(String key) => PreferenceUtils.getTimestamp(key);
  
  static bool containsKey(String key) => PreferenceUtils.containsKey(key);
  static Future<bool> remove(String key) => PreferenceUtils.remove(key);
  static Future<bool> clear() => PreferenceUtils.clear();
}